package com.vae.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.vae.auth.domain.XcUser;
import com.vae.auth.domain.XcUserRole;
import com.vae.auth.dto.AuthParamsDto;
import com.vae.auth.dto.XcUserExt;
import com.vae.auth.mapper.XcUserMapper;
import com.vae.auth.mapper.XcUserRoleMapper;
import com.vae.auth.service.AuthService;
import com.vae.auth.service.WxAuthService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
/**
 * 微信扫码登录的时候，如果扫码成功，那么请求回来到这里
 */
@Service("wx_authservice")//指定bean的名称，在UserServiceImpl里面有使用到这个bean名称，注意bean名称是"xx_authservice"的格式
public class WxAuthServiceImpl implements AuthService, WxAuthService {

    @Autowired
    XcUserMapper xcUserMapper;

    @Autowired
    RestTemplate restTemplate;

    @Value("${weixin.appid}")
    String appid;

    @Value("${weixin.secret}")
    String secret;

    @Autowired
    XcUserRoleMapper xcUserRoleMapper;

    @Autowired
    WxAuthServiceImpl currentPorxy;

    @Override
    public XcUserExt execute(AuthParamsDto authParamsDto) {
        //得到账号
        String username = authParamsDto.getUsername();
        //查询数据库
        XcUser user = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username));
        if(user==null){
            //返回空表示用户不存在
            throw new RuntimeException("用户不存在，登录失败");
        }
        XcUserExt xcUserExt = new XcUserExt();
        BeanUtils.copyProperties(user,xcUserExt);
        return xcUserExt;
    }

    @Override
    public XcUser wxAuth(String code){

        //收到code调用微信接口申请access_token
        Map<String, String> access_token_map = getAccess_token(code);
        if(access_token_map==null){
            return null;
        }
        System.out.println(access_token_map);
        String openid = access_token_map.get("openid");
        String access_token = access_token_map.get("access_token");
        //携带令牌查询用户信息
        Map<String, String> userinfo = getUserinfo(access_token, openid);

        // 保存用户信息到数据库。非事务方法，去调用事务方法，那么会导致事务方法的事务失效。
        // 解决: 非事务方法 -> 代理 -> 事务方法
        // 具体做法: 事务方法和非事务方法都在同一个类，那么就在这个类@Autowired注入自己，然后在非事务方法里面通过 "自己".非事务方法
        XcUser xcUser = currentPorxy.addWxUser(userinfo);

        return xcUser;
    }

    /**
     * 申请访问令牌,响应示例
     {
     "access_token":"ACCESS_TOKEN",
     "expires_in":7200,
     "refresh_token":"REFRESH_TOKEN",
     "openid":"OPENID",
     "scope":"SCOPE",
     "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
     }
     */
    private Map<String,String> getAccess_token(String code) {

        String wxUrl_template = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
        //请求微信地址
        String wxUrl = String.format(wxUrl_template, appid, secret, code);

        System.out.println("调用微信接口申请access_token的URL: "+wxUrl);

        ResponseEntity<String> exchange = restTemplate.exchange(wxUrl, HttpMethod.POST, null, String.class);

        String result = exchange.getBody();

        System.out.println("调用微信接口申请access_token的响应数据: "+result);
        Map<String,String> resultMap = JSON.parseObject(result, Map.class);

        return resultMap;
    }

    /**获取用户信息，示例如下：
     {
     "openid":"OPENID",
     "nickname":"NICKNAME",
     "sex":1,
     "province":"PROVINCE",
     "city":"CITY",
     "country":"COUNTRY",
     "headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmfHe/0",
     "privilege":[
     "PRIVILEGE1",
     "PRIVILEGE2"
     ],
     "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
     }
     */
    private Map<String,String> getUserinfo(String access_token,String openid) {

        String wxUrl_template = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
        //请求微信地址
        String wxUrl = String.format(wxUrl_template, access_token, openid);

        System.out.println("调用微信接口申请access_token的URL: "+wxUrl);

        ResponseEntity<String> exchange = restTemplate.exchange(wxUrl, HttpMethod.GET, null, String.class);

        //防止乱码进行转码
        String result = new String(exchange.getBody().getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
        System.out.println("调用微信接口申请access_token的响应数据: "+result);
        Map<String,String> resultMap = JSON.parseObject(result, Map.class);

        return resultMap;
    }

    /**
     * 拿到用户信息之后，保存用户信息
     */
    @Transactional
    public XcUser addWxUser(Map userInfo_map){
        String unionid = userInfo_map.get("unionid").toString();
        //根据unionid查询数据库
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getWxUnionid, unionid));
        if(xcUser!=null){
            String headimgurl = userInfo_map.get("headimgurl").toString();
            LambdaUpdateWrapper<XcUser> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(XcUser::getWxUnionid, unionid);
            updateWrapper.set(XcUser::getUserpic, headimgurl);
            updateWrapper.set(XcUser::getName, userInfo_map.get("nickname").toString());
            updateWrapper.set(XcUser::getNickname, userInfo_map.get("nickname").toString());
            updateWrapper.set(XcUser::getUpdateTime, new Date());
            xcUserMapper.update(null, updateWrapper);
            return xcUser;
        }
        String userId = String.valueOf(System.currentTimeMillis());
        xcUser = new XcUser();
        xcUser.setId(userId);
        xcUser.setWxUnionid(unionid);
        //记录从微信得到的昵称
        xcUser.setUserpic(userInfo_map.get("headimgurl").toString());
        xcUser.setName(userInfo_map.get("nickname").toString());
        xcUser.setUsername(userInfo_map.get("unionid").toString());//在认证的时候就是读这个username，为了唯一性，username就存unionid
        xcUser.setNickname(userInfo_map.get("nickname").toString());
        xcUser.setPassword(unionid);
        xcUser.setUtype("101001");//学生类型
        xcUser.setCompanyId(userId);//虽然是学生类型，但是为了后续拓展，给一个companyId
        xcUser.setStatus("1");//用户状态
        xcUser.setCreateTime(new Date());
        xcUserMapper.insert(xcUser);
        XcUserRole xcUserRole = new XcUserRole();
        xcUserRole.setId(UUID.randomUUID().toString());
        xcUserRole.setUserId(userId);
        xcUserRole.setRoleId("104");//学生角色
        xcUserRole.setCreateTime(new Date());
        xcUserRole.setCreator("微信扫码注册");
        xcUserRoleMapper.insert(xcUserRole);
        return xcUser;
    }
}
